﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics.Contracts;

using Seven.Web.IntelligentQuery.Model;

namespace Seven.Web.IntelligentQuery.Extensions
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class MvcHtmlStringExtensions
    {
        internal static readonly char methodPrefix = '[';
        internal static readonly char methodPostfix = ']';
        internal static readonly char prefixPrefix = '(';
        internal static readonly char prefixPostfix = ')';
        internal static readonly char andStr = '&';
        internal static readonly char equalStr = '=';

        /// <summary>
        /// 为当前表单元素添加搜索条件
        /// </summary>
        /// <param name="str"></param>
        /// <param name="method">搜索方法</param>
        /// <param name="prefix">前缀</param>
        /// <returns></returns>
        public static MvcHtmlWrapper ForQuery(this IHtmlString str, QueryMethod? method, string prefix = "")
        {
            var wrapper = MvcHtmlWrapper.Create(str);
            Contract.Assert(null != wrapper);
            if (!method.HasValue) { return wrapper; }
            var html = wrapper.HtmlString;

            #region 如果是CheckBox，则去掉hidden

            if (html.Contains("type=\"checkbox\""))
            {
                var checkMatch = Regex.Match(html, "<input name=\"[^\"]+\" type=\"hidden\" [^>]+ />");
                if (checkMatch.Success)
                {
                    wrapper.Add(checkMatch.Groups[0].Value, string.Empty);
                }
            }

            #endregion

            #region 替换掉Name，从Name替换成[method](prefix)Name，若prefix不存在则替换成[method]Name

            var match = Regex.Match(html, "name=\"(?<name>[^\"]+)\"");
            var strInsert = "";
            if (!string.IsNullOrWhiteSpace(prefix))
            {
                strInsert += string.Format("{1}{0}{2}", prefix, prefixPrefix, prefixPostfix);
            }
            if (match.Success)
            {
                wrapper.Add(match.Groups[0].Value,
                            string.Format("name=\"{3}{1}{4}{2}{0}\"", match.Groups[1].Value, method, strInsert, methodPrefix, methodPostfix));
            }

            #endregion

            return wrapper;
        }
    }

    /// <summary>
    /// MvcHtmlString包装器
    /// 用于设置对Html的替换规则并在输出时统一处理显示Html
    /// </summary>
    public class MvcHtmlWrapper : IHtmlString
    {
        private string _htmlString;

        /// <summary>
        /// 用于替换的Dict
        /// </summary>
        public List<Tuple<string, string>> ReplaceDict { get; set; }

        IHtmlString HtmlStringInterface { get; set; }

        /// <summary>
        /// 获取MvcHtmlString所生成的Html字符串
        /// </summary>
        public string HtmlString
        {
            get
            {
                if (string.IsNullOrWhiteSpace(this._htmlString))
                {
                    this._htmlString = HtmlStringInterface.ToHtmlString();
                }
                return this._htmlString;
            }
        }

        /// <summary>
        /// 构造MvcHtmlString包装器
        /// </summary>
        /// <param name="str">MvcHtmlString的实例，不允许为空</param>
        MvcHtmlWrapper(IHtmlString str)
        {
            Contract.Requires(str != null);
            HtmlStringInterface = str;
            ReplaceDict = new List<Tuple<string, string>>();
        }

        /// <summary>
        /// 构建一个MvcHtmlWrapper，如果是MvcHtmlWrapper则直接返回，
        /// 如果是是其它类型则构造MvcHtmlWrapper后返回
        /// </summary>
        /// <param name="str">IHtmlString类型，实现了ToHtmlString接口的类型</param>
        /// <returns></returns>
        public static MvcHtmlWrapper Create(IHtmlString str)
        {
            Contract.Requires(str != null);
            if (str is MvcHtmlWrapper)
            { return str as MvcHtmlWrapper; }
            if (str is MvcHtmlString)
            { return new MvcHtmlWrapper(str); }
            Contract.Assert(false);
            return null;
        }

        /// <summary>
        /// 添加替换原则
        /// </summary>
        /// <param name="item1">被替换的字符串</param>
        /// <param name="item2">替换为的字符串</param>
        internal void Add(string item1, string item2)
        {
            ReplaceDict.Add(Tuple.Create(item1, item2));
        }

        /// <summary>
        /// 对ToHtmlString进行了重写， 输出HtmlString的内容，并按替换规则进行了替换
        /// </summary>
        /// <returns></returns>
        public string ToHtmlString()
        {
            return this.ToString();
        }

        /// <summary>
        /// 对ToString进行了重写， 输出HtmlString的内容，并按替换规则进行了替换
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            var sb = new StringBuilder(HtmlString);
            foreach (var item in ReplaceDict)
            {
                if (!string.IsNullOrEmpty(item.Item1))
                {
                    sb.Replace(item.Item1, item.Item2);
                }
            }
            return sb.ToString();
        }
    }
}
